﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Entity.Infrastructure;
using QuanLyHocPhi.Model;
using System.Data.Entity;

namespace QuanLyHocPhi.BLL
{
    partial class BizLopHocPhan
    {
        /// <summary>
        /// Lấy danh sách sinh viên với đầy đủ thông tin Mã sinh viên, MaLopHocPhan, HeSoMienGiam, MaPhieuThu,
        /// SinhVien, SinhVien.LớpGốc
        /// </summary>
        /// <param name="lopHocPhan"></param>
        /// <returns></returns>
        internal static IList<LopHocPhan_SinhVien> GetList_SinhVienFullDetails(LopHocPhan lopHocPhan)
        {
            using (var context = new QLHPEntities())
            {
                var query = from thongtindangky in context.LopHocPhan_SinhVienDbSet
                                .Include("SinhVien")
                                .Include("SinhVien.Lop")
                            where thongtindangky.MaLopHocPhan == lopHocPhan.MaLopHocPhan
                            orderby thongtindangky.SinhVien.Ten
                            select thongtindangky;
                List<LopHocPhan_SinhVien> lstThongTinDangKy = query.ToList();
                return lstThongTinDangKy;
            }
        }

        /// <summary>
        /// Danh sách lớp học phần trong học kỳ cụ thể
        /// </summary>
        /// <param name="hocKy"></param>
        /// <returns></returns>
        internal static IList<LopHocPhan> GetList_LopHocPhan(HocKy hocKy)
        {
            using (var context = new QLHPEntities())
            {
                try
                {
                    var query = (from lhp in context.LopHocPhanDbSet
                                 where lhp.MaHocKy == hocKy.MaHocKy
                                 select lhp);
                    var lstLopHocPhan = query.ToList();
                    if (lstLopHocPhan != null)
                        return lstLopHocPhan.ToSortableBindingList();
                    else
                        return null;
                }
                catch
                {
                    return null;
                }
            }
        }

        internal static void AddNew_LopHocPhan(LopHocPhan lopHocPhan)
        {
            using (var context = new QLHPEntities())
            {
                // Kiểm tra trùng tên lớp học phần trong cùng học kỳ!
                int count = (from lhp in context.LopHocPhanDbSet
                             where lhp.TenLopHocPhan == lopHocPhan.TenLopHocPhan
                             && lhp.MaHocKy == lopHocPhan.MaHocKy
                             select lhp.MaLopHocPhan).Count();
                if (count > 0)
                    throw new Exception(string.Format(
                        "Đã tồn tại lớp học phần [{0}] trong học kỳ này rồi!", lopHocPhan.TenLopHocPhan));

                // Thực hiện bổ sung
                context.LopHocPhanDbSet.Add(lopHocPhan);
                context.SaveChanges();
            }
        }

        internal static void Update_LopHocPhan(LopHocPhan lopHocPhan)
        {
            using (var context = new QLHPEntities())
            {
                // Kiểm tra sự tồn tại của lớp học phần này
                LopHocPhan oLopHocPhan = (from lhp in context.LopHocPhanDbSet
                                          where lhp.MaLopHocPhan == lopHocPhan.MaLopHocPhan
                                          select lhp).FirstOrDefault();
                if (oLopHocPhan == null)
                    throw new Exception(string.Format("Không tồn tại lớp học phần {0} trong hệ thống!",
                        lopHocPhan.TenLopHocPhan));

                // Kiểm tra trùng tên lớp học phần trong cùng học kỳ!
                int count = (from lhp in context.LopHocPhanDbSet
                             where lhp.TenLopHocPhan == lopHocPhan.TenLopHocPhan
                             && lhp.MaHocKy == lopHocPhan.MaHocKy
                             && lhp.MaLopHocPhan != lopHocPhan.MaLopHocPhan
                             select lhp.MaLopHocPhan).Count();
                if (count > 0)
                    throw new Exception(
                        string.Format("Đã tồn tại lớp học phần [{0}] trong học kỳ này rồi!", lopHocPhan.TenLopHocPhan));

                // Thực hiện cập nhật
                oLopHocPhan.TenLopHocPhan = lopHocPhan.TenLopHocPhan;
                oLopHocPhan.MaHocPhan = lopHocPhan.MaHocPhan;
                oLopHocPhan.HocPhi = lopHocPhan.HocPhi;
                oLopHocPhan.PhuThu = lopHocPhan.PhuThu;
                oLopHocPhan.GiaoVienPhuTrach = lopHocPhan.GiaoVienPhuTrach;
                oLopHocPhan.NgayBatDau = lopHocPhan.NgayBatDau;
                oLopHocPhan.NgayKetThuc = lopHocPhan.NgayKetThuc;
                //oLopHocPhan.GhiChu = lopHocPhan.GhiChu;
                try
                {
                    context.SaveChanges();
                }
                catch (Exception exc)
                {
                    throw new Exception("Không thể cập nhật lớp học phần! Chi tiết lỗi:\n" + exc.Message);
                }
            }
        }

        /// <summary>
        /// Xoá lớp học phần cùng những thông tin có liên quan
        /// </summary>
        /// <param name="lopHocPhan"></param>
        internal static void Delete_LopHocPhan(LopHocPhan lopHocPhan)
        {
            using (var context = new QLHPEntities())
            {
                // Kiểm tra sự tồn tại của lớp học phần này
                LopHocPhan oLopHocPhan = (from lhp in context.LopHocPhanDbSet
                                          where lhp.MaLopHocPhan == lopHocPhan.MaLopHocPhan
                                          select lhp).FirstOrDefault();
                if (oLopHocPhan == null)
                    throw new Exception(string.Format("Không tồn tại lớp học phần {0} trong hệ thống!",
                        lopHocPhan.TenLopHocPhan));

                // TODO: Kiểm tra sự tồn tại của các phiếu thu, trạng thái của lớp học phần

                // Xoá thông tin đăng ký của lớp học phần
                var lstSinhVien = oLopHocPhan.LopHocPhan_SinhVien;
                foreach (var sinhVien in lstSinhVien)
                    oLopHocPhan.LopHocPhan_SinhVien.Remove(sinhVien);

                context.LopHocPhanDbSet.Remove(oLopHocPhan);

                // Lưu thay đổi
                try
                {
                    context.SaveChanges();
                }
                catch (Exception exc)
                {
                    throw new Exception(exc.Message + "\n" + exc.StackTrace);
                }
            }
        }

        /// <summary>
        /// Thực hiện ghi nhận thông tin đăng ký sinh viên
        /// </summary>
        /// <param name="lopHocPhan"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        internal static int DangKy_SinhVienKhongChuyen(LopHocPhan lopHocPhan, System.Data.DataTable dt)
        {
            using (var context = new QLHPEntities())
            {
                var oLopHocPhan = context.LopHocPhanDbSet
                    .Where(lhp => lhp.MaLopHocPhan == lopHocPhan.MaLopHocPhan)
                    .SingleOrDefault();
                if (oLopHocPhan == null)
                    throw new Exception("Lớp học phần không tồn tại trên hệ thống");
                int nDangKy = 0;

                var lstThongTinDangKy = oLopHocPhan.LopHocPhan_SinhVien;

                foreach (System.Data.DataRow row in dt.Rows)
                {
                    object oTrangThai = row[Col_TrangThai];
                    if (oTrangThai == null || oTrangThai == DBNull.Value)
                        continue;
                    string trangThai = oTrangThai.ToString();
                    if (!trangThai.Equals(Status_Ready_DangKy) &&
                        !trangThai.Equals(Status_Ready_TaoSVVaDangKy))
                        continue;

                    #region Bổ sung sinh viên + Đăng ký vào lớp
                    string maSinhVien = Convert.ToString(row[Col_MaSinhVien]);
                    string hoDem = Convert.ToString(row[Col_HoDem]);
                    string ten = Convert.ToString(row[Col_Ten]);
                    string ngaySinh = Convert.ToString(row[Col_NgaySinh]);
                    if (ngaySinh != null)
                    {
                        if (ngaySinh.Length > 10)
                            ngaySinh = ngaySinh.Trim().Substring(0, 10);
                    }
                    string maLopGoc = Convert.ToString(row[Col_MaLopGoc]);
                    if (trangThai == Status_Ready_TaoSVVaDangKy)
                    {
                        #region Bổ sung sinh viên vào hệ thống
                        SinhVien sinhVien = new SinhVien
                        {
                            MaSinhVien = maSinhVien,
                            HoDem = hoDem,
                            Ten = ten,
                            NgaySinh = ngaySinh,
                            KC_MaLop = maLopGoc,
                            HeSoMienGiam = 0
                        };
                        try
                        {
                            context.SinhVienDbSet.Add(sinhVien);
                            context.SaveChanges();
                        }
                        catch (Exception exc)
                        {
                            throw new Exception(
                                string.Format("Đã đăng ký được {0} sinh viên\n" +
                                    "Xuất hiện lỗi khi tiến hành nạp sinh viên {1} vào hệ thống!",
                                    nDangKy, hoDem + " " + ten), exc);
                        }
                        #endregion
                    }

                    #region Đăng ký vào lớp học phần
                    try
                    {
                        var thongTinDangKy = new LopHocPhan_SinhVien
                        {
                            MaSinhVien = maSinhVien,
                            MaLopHocPhan = oLopHocPhan.MaLopHocPhan,
                            MaPhieuThu = null,
                            HeSoMienGiam = 0
                        };
                        oLopHocPhan.LopHocPhan_SinhVien.Add(thongTinDangKy);
                        context.SaveChanges();
                        nDangKy++;
                    }
                    catch (Exception exc)
                    {
                        throw new Exception(
                            string.Format("Đã đăng ký được {0} sinh viên\n" +
                                "Xuất hiện lỗi khi đăng ký sinh viên {1} vào lớp học phần.", nDangKy, hoDem + " " + ten), exc);
                    }
                    #endregion
                    #endregion
                }
                return nDangKy;
            }
        }

        internal static void BoDangKy_SinhVienKhongChuyen(LopHocPhan m_LopHocPhan, SinhVien selectedSinhVien)
        {
            using (var context = new QLHPEntities())
            {
                string sql = "delete from LopHocPhan_SinhVien where MaLopHocPhan={0} and MaSinhVien={1}";
                int n = context.Database.ExecuteSqlCommand(sql, m_LopHocPhan.MaLopHocPhan, selectedSinhVien.MaSinhVien);
                if (n != 1)
                    throw new Exception("Không có dòng nào được xoá!");
            }
        }

        internal static void Delete_ThongTinDangKyLopHocPhan(LopHocPhan m_LopHocPhan, string maSinhVien)
        {
            using (var context = new QLHPEntities())
            {

                LopHocPhan_SinhVien lhp_sv = (from lhp in context.LopHocPhan_SinhVienDbSet
                                              where lhp.MaSinhVien == maSinhVien && lhp.MaLopHocPhan == m_LopHocPhan.MaLopHocPhan
                                              select lhp).FirstOrDefault();
                if (lhp_sv == null)
                    throw new Exception("Không có dòng nào được xoá!");
                else
                    if (string.IsNullOrEmpty(lhp_sv.MaPhieuThu))
                    {
                        string sql = "delete from LopHocPhan_SinhVien where MaLopHocPhan={0} and MaSinhVien={1}";
                        int n = context.Database.ExecuteSqlCommand(sql, m_LopHocPhan.MaLopHocPhan, maSinhVien);
                        if (n != 1)
                            throw new Exception("Không có dòng nào được xoá!");
                    }
                    else
                        throw new Exception("Bạn phải xóa phiếu thu của sinh viên này trước khi rút khỏi danh sách!");
            }
        }
        internal static void Delete_ThongTinDangKyLopHocPhan(string maLopHocPhan, string maSinhVien)
        {
            using (var context = new QLHPEntities())
            {
                string sql = "delete from LopHocPhan_SinhVien where MaLopHocPhan={0} and MaSinhVien={1}";
                int n = context.Database.ExecuteSqlCommand(sql, maLopHocPhan, maSinhVien);
                if (n != 1)
                    throw new Exception("Không có dòng nào được xoá!");
            }
        }

        /// <summary>
        /// Lấy lớp học phần theo mã lớp học phần
        /// </summary>
        /// <param name="maLopHP"></param>
        /// <returns></returns>
        internal static LopHocPhan GetLopHocPhanByMaLHP(string maLopHP)
        {
            using (var context = new QLHPEntities())
            {
                var lopHocPhan = context.LopHocPhanDbSet.Include(e => e.HocKy).Where(e => e.MaLopHocPhan.Equals(maLopHP)).SingleOrDefault();
                return lopHocPhan;
            }
        }

        internal static List<string> GetListMaHP(string namHoc, int hocKy)
        {
            using (var context = new QLHPEntities())
            {
                var listmaLopHP = from e in context.LopHocPhanDbSet
                                  where e.HocKy.NamHoc == namHoc && e.HocKy.SoHieuHocKy == hocKy
                                  select e.MaLopHocPhan;
                return listmaLopHP.ToList();
            }
        }

        internal static LopHocPhan GetDefaultNew_LopHocPhan(HocKy hocKy)
        {
            using (var context = new QLHPEntities())
            {
                hocKy = context.HocKyDbSet.Where(hk => hk.MaHocKy == hocKy.MaHocKy).FirstOrDefault();
                return new LopHocPhan
                {
                    MaLopHocPhan = Guid.NewGuid().ToString(),
                    TenLopHocPhan = "",
                    TrangThaiHoatDong = LopHocPhan.TrangThai_ChuaThuXongHocPhi,
                    MaHocKy = hocKy.MaHocKy,
                    HocPhi = hocKy.HocPhiKhongChuyen,
                    PhuThu = -hocKy.PhuThuKhongChuyen
                };
            }
        }

        internal static List<LopHocPhan> GetList_LopHocPhan()
        {
            using (var context = new QLHPEntities())
            {
                return context.LopHocPhanDbSet.OrderByDescending(e => e.HocKy.NamHoc).OrderByDescending(e => e.HocKy.SoHieuHocKy).ToList();
            }
        }

        internal static List<LopHocPhan> GetListLopHocPhan(string maTruong, int khoaTuyenSinh, string namHoc, int hocKy)
        {
            using (var context = new QLHPEntities())
            {
                var listLHPSV = (from e in context.LopHocPhan_SinhVienDbSet
                                 where
                                 (
                                 e.SinhVien.Lop.Truong.MaTruong == maTruong &&
                                       e.SinhVien.Lop.NamTuyenSinh == khoaTuyenSinh &&
                                       e.LopHocPhan.HocKy.SoHieuHocKy == hocKy &&
                                       e.LopHocPhan.HocKy.NamHoc == namHoc
                                 )
                                 select e.MaLopHocPhan).ToList();
                var list = from e in context.LopHocPhanDbSet
                           where listLHPSV.Contains(e.MaLopHocPhan)
                           select e;
                return list.ToList();
            }
        }

        /// <summary>
        /// Biên chế 1 sinh viên không chuyên vào lớp học phần
        /// </summary>
        /// <param name="m_ThongTinDangKy"></param>
        internal static void AddNew_ThongTinDangKy(LopHocPhan_SinhVien thongTinDangKy)
        {
            using (var context = new QLHPEntities())
            {
                try
                {
                    int oCount = (from ttdk in context.LopHocPhan_SinhVienDbSet
                                  where ttdk.MaSinhVien == thongTinDangKy.MaSinhVien &&
                                  ttdk.MaLopHocPhan == thongTinDangKy.MaLopHocPhan
                                  select ttdk).Count();
                    if (oCount > 0)
                        throw new Exception("Thông tin đăng ký sinh viên vào lớp học phần đã tồn tại trên hệ thống");
                    context.LopHocPhan_SinhVienDbSet.Add(thongTinDangKy);
                    context.SaveChanges();
                }
                catch (Exception exc)
                {
                    throw new Exception("Không thể đăng ký sinh viên vào lớp học phần ", exc);
                }
            }
        }

        /// <summary>
        /// Chỉnh sửa thông tin biên chế sinh viên trong lớp học phần (thay đổi hệ số miễn giảm)
        /// </summary>
        /// <param name="m_ThongTinDangKy"></param>
        internal static void Update_ThongTinDangKy(LopHocPhan_SinhVien thongTinDangKy)
        {
            using (var context = new QLHPEntities())
            {
                try
                {
                    var oThongTinDangKy = (from ttdk in context.LopHocPhan_SinhVienDbSet
                                           where ttdk.MaLopHocPhan == thongTinDangKy.MaLopHocPhan &&
                                           ttdk.MaSinhVien == thongTinDangKy.MaSinhVien
                                           select ttdk).FirstOrDefault();
                    if (oThongTinDangKy == null)
                        throw new Exception("Thông tin đăng ký sinh viên trong lớp học phần không tồn tại trên hệ thống");
                    oThongTinDangKy.HeSoMienGiam = thongTinDangKy.HeSoMienGiam;
                    context.SaveChanges();
                }
                catch (Exception exc)
                {
                    throw new Exception("Không thể cập nhật thông tin đăng ký sinh viên trong lớp học phần", exc);
                }
            }
        }
        internal static bool UpdateMaTruong()
        {
            using (var context = new QLHPEntities())
            {
                var dsLHP = (from e in context.LopHocPhan_SinhVienDbSet
                             select e.LopHocPhan
                                    ).Distinct().ToList();
                foreach (var item in dsLHP)
                {
                    if (item.LopHocPhan_SinhVien != null && item.LopHocPhan_SinhVien.ToList().Count > 0)
                    {
                        for (int i = 0; i < item.LopHocPhan_SinhVien.ToList().Count; i++)
                            if (item.LopHocPhan_SinhVien.ToList()[i].SinhVien != null)
                            {
                                SinhVien a = item.LopHocPhan_SinhVien.ToList()[i].SinhVien;
                                Lop l = a.Lop;
                                Truong t = l.Truong;
                                item.MaTruong = t.MaTruong;
                                break;
                            }
                    }
                }
                context.SaveChanges();
                return true;
            }
        }
        internal static IList<LopHocPhan> GetList_LopHocPhan(HocKy hocKy, string maTruong)
        {
            using (var context = new QLHPEntities())
            {
                try
                {
                    var dsLHP = (from e in context.LopHocPhanDbSet
                                 where
                                     (
                                         (e.MaTruong == maTruong &&
                                         e.HocKy.MaHocKy == hocKy.MaHocKy)
                                      //   ||
                                      //   (e.LopHocPhan_SinhVien.Count == 0
                                      //&& e.HocKy.MaHocKy == hocKy.MaHocKy)
                                     )
                                 select e
                                ).ToList();
                    //var dsLHPTrong = (from lhp in context.LopHocPhanDbSet
                    //                  where lhp.LopHocPhan_SinhVien.Count == 0
                    //                  && lhp.HocKy.MaHocKy == hocKy.MaHocKy
                    //                  select lhp).ToList();
                    //dsLHP.AddRange(dsLHPTrong);
                    return dsLHP.ToSortableBindingList();
                }
                catch
                {
                    return null;
                }
            }
        }

        internal static void UpdateLHP_SV(string maSinhVien, string maLopHP, string ghiChu)
        {
            using (var context = new QLHPEntities())
            {
                try
                {
                    var thongTin = (from ttdk in context.LopHocPhan_SinhVienDbSet
                                    where ttdk.MaLopHocPhan == maLopHP &&
                                    ttdk.MaSinhVien == maSinhVien
                                    select ttdk).FirstOrDefault();
                    if (thongTin == null)
                        throw new Exception("Thông tin đăng ký sinh viên trong lớp học phần không tồn tại trên hệ thống");
                    thongTin.GhiChu = ghiChu;
                    context.SaveChanges();
                }
                catch (Exception exc)
                {
                    throw new Exception("Không thể cập nhật thông tin đăng ký sinh viên trong lớp học phần", exc);
                }
            }
        }
    }
}
